package com.wanfajie.smsdistribute.common.adapter

import android.content.Context
import android.support.annotation.CallSuper
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.TextView
import com.wanfajie.smsdistribute.common.widget.SlideIndexView
import com.wanfajie.smsdistribute.util.HanYuComparator
import com.wanfajie.smsdistribute.util.pinyinInitial

abstract class SlideLeadRecyclerAdapter<E>(
        ctx: Context,
        items: Collection<E>,
        resId: Int,
        checkableId: Int,
        private val leadId: Int = 0,
        private val leadHide: Int = View.GONE,
        private val selector: (E) -> String
) : CheckedRecyclerAdapter<E>(
        ctx,
        items.sortedWith(compareBy(HanYuComparator.DEFAULT, selector)),
        resId,
        checkableId
), SlideIndexView.OnItemSlideListener {

    init {
        setOnLongClickListener { true }
        registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
            override fun onChanged() {
                val recyclerList = mItems as RecyclerAdapterLinkedList<E, CheckedViewHolder>
                recyclerList silent {
                    sortWith(compareBy(HanYuComparator.DEFAULT, selector))
                }
                findLeadItems()
            }

            override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
                notifyDataSetChanged()
            }

            override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
                notifyDataSetChanged()
            }

            override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
                notifyDataSetChanged()
            }

            override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
                findLeadItems()
            }
        })
    }

    private val mLeadItems: MutableMap<E, Char> = HashMap()
    private val mLeadChars: MutableMap<Char, E> = HashMap()
    private val mLeadPos: MutableMap<Char, Int> = HashMap()
    var isShowLead = true
        set(v) {
            field = v
            notifyDataSetChanged()
        }

    @CallSuper
    override fun processViewHolder(p0: CheckedViewHolder, p1: E) {
        if (leadId != 0) {
            val leadTextView = p0.get<TextView>(leadId)
            if (p1 in mLeadItems && isShowLead) {
                leadTextView.visibility = View.VISIBLE
                leadTextView.text = mLeadItems[p1].toString()
            } else {
                leadTextView.visibility = leadHide
            }
        }
    }

    private fun findLeadItems() {
        mLeadChars.clear()
        mLeadItems.clear()
        mLeadPos.clear()

        if (mItems.size > 0) {
            val first = getItem(0)
            val char = selector(first).pinyinInitial[0]
            if (char.isLetter()) {
                mLeadItems[first] = char
                mLeadChars[char] = first
            } else {
                mLeadItems[first] = '#'
                mLeadChars['#'] = first
            }
            mLeadPos[char] = 0
        }

        for (i in 1 until mItems.size) {
            val prev = getItem(i-1)
            val curr = getItem(i)
            val prevChar = selector(prev).pinyinInitial[0]
            val currChar = selector(curr).pinyinInitial[0]

            when {
                currChar.isLetter() && currChar != prevChar -> {
                    mLeadItems[curr] = currChar
                    mLeadChars[currChar] = curr
                    mLeadPos[currChar] = i
                }
                prevChar.isLetter() && !currChar.isLetter() -> {
                    mLeadItems[curr] = '*'
                    mLeadChars['*'] = curr
                    mLeadPos[currChar] = i
                }
            }
        }
    }

    fun scrollTo(ch: Char) {
        val pos = mLeadPos[ch]
        if (pos != null) {
            val manager = mRecyclerView?.layoutManager as LinearLayoutManager?
            manager?.scrollToPositionWithOffset(pos, 0)
        }
    }

    override fun onItemSlide(item: CharSequence) {
        scrollTo(item[0])
    }

    final override fun setOnLongClickListener(listener: (View) -> Boolean) {
        super.setOnLongClickListener(listener)
    }

    final override fun registerAdapterDataObserver(observer: RecyclerView.AdapterDataObserver) {
        super.registerAdapterDataObserver(observer)
    }
}
